package moe.oil.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.log4j.Log4j2;
import moe.oil.config.ConfigSecurity;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Log4j2
@Data
@Accessors(chain = true)
public class JwtUtils {

    private static final String SECRET = ConfigSecurity.SECURITY_KEY;
    private static final long EXPIRE = ConfigSecurity.SESSION_EXPIRATION_TIME;

    private Instant createDate ;
    private Instant expireDate ;

    /**
     * 生成jwt token
     */
    public String createToken(Long userId, String username) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userId);
        claims.put("username", username);

        //过期时间
        createDate=Instant.now();

        expireDate = Date.from(createDate).toInstant();
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(Date.from(expireDate.minusMillis(ConfigSecurity.SESSION_EXPIRATION_TIME)))
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
    }

    public Claims getClaimByToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            log.debug("validate is token error  ", e);
            return null;
        }
    }

    public Integer getUserIdByRequest(HttpServletRequest request) {
        String body;
        String token = request.getHeader("Authorization");
        if (token == null || token.equals("")) {
            System.out.println("1");
            return null;
        }
        if (!token.startsWith("Bearer ") || token.split(" ").length != 2) {
            System.out.println("2");
            return null;
        }
        body = token.split(" ")[1];

        return getClaimByToken(body).get("userId", Integer.class);
    }

    /**
     * token是否过期
     *
     * @return true：过期
     */
    public boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }
}
